﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using MageWars.GameElements;

namespace MageWars.Support.StateMachines.Behaviors
{
    public class Seek : Behavior
    {
        public Vector2 target_position { get; set; }

        public Queue<Node> camino { get; set; }

        public Node target_node { get; set; }

        public Node current_node { get; set; }

        public Node next_node { get; set; }



        public Seek(Mage Self, Vector2 target_position)
        {
            this.target_position = target_position;
            this.World = Mesh.GetMesh();
            this.camino = null;
            this.Self = Self;
            this.target_node = GetNearbyNode(target_position);
            this.current_node = GetNearbyNode(new Vector2(Self.Position.X, Self.Position.Y));
        }

        public Seek(Mage Self, Point target_position)
            : this(Self, new Vector2(target_position.X, target_position.Y))
        {
        }



        public Node GetNearbyNode(Vector2 position)
        {
            Rectangle aa;

            foreach (var nodo in World.RectNodes.Keys)
            {
                aa = nodo;
                aa.Inflate(1, 1);
                if (aa.Contains((int)position.X, (int)position.Y))
                {
                    return World.RectNodes[nodo];
                }
            }
            return null;
        }

        public override MWAction GetNextAction()
        {
            if (current_node == null)
            {
                return new MWAction();
            }

            Node TN = GetNearbyNode(target_position);
            MWAction action = new MWAction();
            if (current_node == TN)
            {
                Point target_point = new Point((int)target_position.X, (int)target_position.Y);
                action.Direction = MageMath.getAngle(Self.Position, target_point);
                action.Fire = false;
                action.Jump = false;
                if (Self.BoundingBox.Contains(target_point))
                {
                    action.Speed = 0f;
                    action.Finished = true;
                }
                else
                {
                    action.Speed = 1f;
                    action.Finished = false;
                }
            }
            else if (target_node != TN || camino == null)
            {
                target_node = TN;
                camino = new Queue<Node>(World.Search(current_node, TN));
                if (camino.Count > 0)
                    next_node = camino.Peek();
            }
            else
            {
                if (Self.BoundingBox.Contains(next_node.Position))
                {
                    if (camino.Count == 0)
                    {
                        return new MWAction() { Finished = true };
                    }
                    current_node = camino.Dequeue();
                    if (camino.Count > 0)
                        next_node = camino.Peek();
                }
                bool valido = false;
                action.Direction = MageMath.getAngle(Self.Position, next_node.Position);
                action.Speed = 1.0f;
                action.Fire = false;
                action.Jump = false;
                action.Finished = false;
                while (!valido)
                {
                    foreach (var m in Mage.Mages)
                    {
                        if ((MageMath.GetDistance(Self.Position, m.Position) < 20) &&
                            ((Math.Abs((float)MageMath.getAngle(Self.Position, m.Position) - (float)action.Direction)) < MathHelper.PiOver4))
                        {
                            action.Direction += MathHelper.PiOver4;
                            valido = false;
                            break;
                        }
                        else
                            valido = true;
                    }
                }
            }
            return action;
        }

        public override Node[] GetCamino()
        {
            if (camino != null)
            {
                return camino.ToArray();
            }
            else
            {
                return new Node[] { };
            }
        }
    }
}
